package com.tanhua.server.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.tanhua.common.service.PicUploadService;
import com.tanhua.common.utils.RelativeDateFormat;
import com.tanhua.common.utils.UserThreadLocal;
import com.tanhua.common.vo.ErrorResult;
import com.tanhua.common.vo.PicUploadResult;
import com.tanhua.dubbo.api.QuanZiApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.UserLocationApi;
import com.tanhua.dubbo.api.VisitorsApi;
import com.tanhua.dubbo.pojo.Comment;
import com.tanhua.dubbo.pojo.Publish;
import com.tanhua.dubbo.pojo.UserInfo;
import com.tanhua.dubbo.pojo.Visitors;
import com.tanhua.dubbo.vo.PageInfo;
import com.tanhua.dubbo.vo.UserLocationVo;
import com.tanhua.server.config.DefaultConfig;
import com.tanhua.server.utils.DistanceService;
import com.tanhua.server.vo.CommentVo;
import com.tanhua.server.vo.PageResult;
import com.tanhua.server.vo.QuanZiVo;
import com.tanhua.server.vo.VisitorsVo;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class QuanZiService {

    @DubboReference(version = "1.0.0")
    private QuanZiApi quanZiApi;

    @Autowired
    private UserService userService;

    @DubboReference(version = "1.0.0")
    private UserInfoApi userInfoApi;

    @DubboReference(version = "1.0.0")
    private VisitorsApi visitorsApi;

    @DubboReference(version = "1.0.0")
    private UserLocationApi userLocationApi;

    @Autowired
    private PicUploadService picUploadService;

    @Autowired
    private QuanziMQService quanziMQService;

    @Autowired
    private DefaultConfig defaultConfig;

    /**
     * 查询好友动态
     *
     * @param page
     * @param pageSize
     * @return
     */
    public Object queryPublishList(Integer page, Integer pageSize) {
        Long userId = UserThreadLocal.get();

        PageResult pageResult = new PageResult();
        pageResult.setPagesize(pageSize);
        pageResult.setPage(page);

        //查询好友的动态
        PageInfo<Publish> pageInfo = this.quanZiApi.queryPublishList(userId, page, pageSize);
        List<Publish> records = pageInfo.getRecords();
        if (CollUtil.isEmpty(records)) {
            return pageResult;
        }

        pageResult.setItems(this.fillQuanZiVo(records));
        return pageResult;
    }

    private List<QuanZiVo> fillQuanZiVo(List<Publish> records) {
        Long userId = UserThreadLocal.get();
        //封装成QuanZiVo列表
        //查询动态发布人的用户信息列表
        Map<Long, UserInfo> userInfoMap = this.userInfoApi.queryMapByUserIdList(CollUtil.getFieldValues(records, "userId"));

        List<QuanZiVo> quanZiVoList = new ArrayList<>();

        for (Publish record : records) {
            String publishId = record.getId().toString();
            QuanZiVo quanZiVo = BeanUtil.toBeanIgnoreError(record, QuanZiVo.class);
            quanZiVo.setDistance(this.getDistance(userId,record)+"km"); //距离
            quanZiVo.setCreateDate(RelativeDateFormat.format(new Date(record.getCreated()))); //发布时间 如: 10分钟前
            quanZiVo.setLikeCount(Convert.toInt(this.quanZiApi.queryLikeCount(quanZiVo.getId()))); // 点赞数
            quanZiVo.setLoveCount(Convert.toInt(this.quanZiApi.queryLoveCount(quanZiVo.getId()))); // 喜欢数
            quanZiVo.setCommentCount(Convert.toInt(this.quanZiApi.queryCommentCount(quanZiVo.getId())));
            quanZiVo.setHasLoved(this.quanZiApi.queryUserIsLove(userId, quanZiVo.getId()) ? 1 : 0); // 是否喜欢
            quanZiVo.setHasLiked(this.quanZiApi.queryUserIsLike(userId, quanZiVo.getId()) ? 1 : 0); // 是否点赞

            //填充用户信息
            UserInfo userInfo = userInfoMap.get(record.getUserId());//TODO
            BeanUtil.copyProperties(userInfo, quanZiVo, "id");
            quanZiVo.setGender(userInfo.getSex().name().toLowerCase());

            quanZiVoList.add(quanZiVo);
        }
        return quanZiVoList;
    }

    //获取动态的距离
    public String getDistance(Long userId,Publish record){
        UserLocationVo userLocationVo = this.userLocationApi.queryByUserId(userId);
         double distance = DistanceService.getDistance(userLocationVo.getLatitude(), userLocationVo.getLongitude(),
                 Convert.toDouble(record.getLatitude()),Convert.toDouble(record.getLongitude()));
        return Convert.toStr(distance);
    }

    /**
     * 发布动态
     *
     * @param textContent
     * @param location
     * @param latitude
     * @param longitude
     * @param multipartFile
     * @return
     */
    public Object savePublish(String textContent, String location, String latitude,
                              String longitude, MultipartFile[] multipartFile) {

        Publish publish = new Publish();
        publish.setUserId(UserThreadLocal.get());
        publish.setText(textContent);
        publish.setLocationName(location);
        publish.setLongitude(longitude);
        publish.setLatitude(latitude);
        publish.setMedias(new ArrayList<>());

        //上传图片
        if (ArrayUtil.isNotEmpty(multipartFile)) {
            for (MultipartFile file : multipartFile) {
                PicUploadResult uploadResult = this.picUploadService.upload(file);
                if (StrUtil.isNotEmpty(uploadResult.getName())) {
                    publish.getMedias().add(uploadResult.getName());
                }
            }
        }

        String result = this.quanZiApi.savePublish(publish);
        if (StrUtil.isNotEmpty(result)) {

            //发布成功后发送消息
            this.quanziMQService.publishMsg(result);

            return null;
        }

        return ErrorResult.builder().errCode("500")
                .errMessage("发布动态失败！").build();
    }
    //查询推荐动态
    public PageResult queryRecommendPublish(Integer page, Integer pageSize) {
        PageResult pageResult = new PageResult();
        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);

        Long userId = UserThreadLocal.get();
        PageInfo<Publish> pageInfo = this.quanZiApi.queryRecommendPublishList(userId, page, pageSize);
        List<Publish> records = pageInfo.getRecords();
        if (CollUtil.isEmpty(records)) {

            //默认推荐的动态id
            List<String> pidStrList = Arrays.asList(this.defaultConfig.getPid());
            records = this.quanZiApi.queryRecommendPublishListDefault(pidStrList, page, pageSize).getRecords();
        }

        pageResult.setItems(this.fillQuanZiVo(records));
        return pageResult;
    }

    /**
     * 点赞
     *
     * @param publishId
     * @return
     */
    public Long likeComment(String publishId) {
        Long userId = UserThreadLocal.get();
        //点赞
        Boolean result = this.quanZiApi.likeComment(userId, publishId);
        if (result) {
            //发送点赞成功的消息
            this.quanziMQService.likePublishMsg(publishId);

            //查询点赞数
            return this.quanZiApi.queryLikeCount(publishId);
        }
        return 0L;
    }

    /**
     * 取消点赞
     *
     * @param publishId
     * @return
     */
    public Long disLikeComment(String publishId) {
        Long userId = UserThreadLocal.get();
        //取消点赞
        Boolean result = this.quanZiApi.disLikeComment(userId, publishId);
        if (result) {
            //发送取消点赞的消息
            this.quanziMQService.disLikePublishMsg(publishId);

            //查询点赞数
            return this.quanZiApi.queryLikeCount(publishId);
        }
        return 0L;
    }

    public Long loveComment(String publishId) {
        Long userId = UserThreadLocal.get();
        //喜欢
        Boolean result = this.quanZiApi.loveComment(userId, publishId);
        if (result) {

            //查询喜欢数
            return this.quanZiApi.queryLoveCount(publishId);
        }
        return null;
    }

    public Long disLoveComment(String publishId) {
        Long userId = UserThreadLocal.get();
        //取消喜欢
        Boolean result = this.quanZiApi.disLoveComment(userId, publishId);
        if (result) {
            //查询喜欢数
            return this.quanZiApi.queryLoveCount(publishId);
        }
        return null;
    }

    /**
     * 自己的所有动态
     */
    public PageResult queryAlbumList(Long userId, Integer page, Integer pageSize) {
        PageResult pageResult = new PageResult();
        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);

        Long count = this.quanZiApi.queryPublishCount(userId);
        pageResult.setCounts(Convert.toInt(count));

        PageInfo<Publish> pageInfo = this.quanZiApi.queryAlbumList(userId, page, pageSize);
        List<Publish> records = pageInfo.getRecords();
        if (CollUtil.isEmpty(records)) {
            return pageResult;
        }

        pageResult.setItems(this.fillQuanZiVo(records));
        return pageResult;
    }

    public List<VisitorsVo> queryVisitorsList() {
        List<Visitors> visitorsList = this.visitorsApi.queryMyVisitor(UserThreadLocal.get());
        if (CollUtil.isEmpty(visitorsList)) {
            //没有访客
            return Collections.emptyList();
        }

        //获取用户id列表
        List<Object> visitorUserIdList = CollUtil.getFieldValues(visitorsList, "visitorUserId");
        //查询访客的用户信息
        Map<Long, UserInfo> userInfoMap = this.userInfoApi.queryMapByUserIdList(visitorUserIdList);

        return visitorsList.stream().map(visitors -> {
            UserInfo userInfo = userInfoMap.get(visitors.getVisitorUserId());
            VisitorsVo visitorsVo = BeanUtil.toBeanIgnoreError(userInfo, VisitorsVo.class);
            visitorsVo.setGender(userInfo.getSex().name().toLowerCase());
            return visitorsVo;
        }).collect(Collectors.toList());
    }

    public PageResult queryCommentList(String publishId, Integer page, Integer pageSize) {
        PageResult pageResult = new PageResult();
        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);

        PageInfo<Comment> pageInfo = this.quanZiApi.queryCommentList(publishId, page, pageSize);
        List<Comment> commentList = pageInfo.getRecords();
        if (CollUtil.isEmpty(commentList)) {
            return pageResult;
        }

        List<Object> userIdList = CollUtil.getFieldValues(commentList, "userId");
        Map<Long, UserInfo> userInfoMap = this.userInfoApi.queryMapByRecommendUser(userIdList);

        Long userId = UserThreadLocal.get();

        ArrayList<CommentVo> commentVoList = new ArrayList<>();
        for (Comment comment : commentList) {
            UserInfo userInfo = userInfoMap.get(comment.getUserId());
            CommentVo commentVo = new CommentVo();
            commentVo.setId(comment.getId().toHexString());
            commentVo.setAvatar(userInfo.getLogo());
            commentVo.setNickname(userInfo.getNickName());
            commentVo.setContent(comment.getContent());
            commentVo.setCreateDate(DateUtil.format(new Date(comment.getCreated()), "HH:mm"));
            commentVo.setLikeCount(Convert.toInt(this.quanZiApi.queryLikeCount(commentVo.getId())));
            commentVo.setHasLiked(Convert.toInt(this.quanZiApi.queryUserIsLike(userId, commentVo.getId())));

            commentVoList.add(commentVo);
        }
        pageResult.setItems(commentVoList);
        return pageResult;
    }

    public void saveComments(String publishId, String content) {
        Long userId = UserThreadLocal.get();
        this.quanZiApi.saveComment(userId, publishId, content);
    }


    public QuanZiVo queryById(String publishId) {
        Publish publish = this.quanZiApi.queryPublishById(publishId);
        if(null == publish){
            return null;
        }
        return this.fillQuanZiVo(Arrays.asList(publish)).get(0);
    }

}
